package com.lakeworks.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.lakeworks.common.core.domain.AjaxResult;
import com.lakeworks.common.core.domain.entity.SysMenu;
import com.lakeworks.common.core.domain.entity.SysUser;
import com.lakeworks.common.core.domain.model.LoginUser;
import com.lakeworks.common.core.redis.RedisCache;
import com.lakeworks.common.exception.response.ResponseException;
import com.lakeworks.common.utils.SecurityUtils;
import com.lakeworks.domain.vo.WechatUserInfo;
import com.lakeworks.framework.web.service.SysPermissionService;
import com.lakeworks.service.ISysMenuService;
import com.lakeworks.service.IWechatOAuth2Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;

import static com.lakeworks.common.constant.Constants.LOGIN_TOKENS;
import static com.lakeworks.common.core.domain.AjaxResult.error;
import static com.lakeworks.common.core.domain.AjaxResult.success;

/**
 * 登录验证
 *
 * @author lakeworks
 */
@RestController
public class SysLoginController {
    private static final Logger log = LoggerFactory.getLogger(SysLoginController.class);
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private IWechatOAuth2Service wechatOAuth2Service;
    @Autowired
    private RedisCache redisCache;

    /**
     * 微信转发登录
     */
    @GetMapping("/wechat/login")
    public AjaxResult wechatLogin(@RequestParam("code") String code, @RequestParam("state") String state) {
        log.info("微信登录，code：[{}]",code);
        try {
            JSONObject jsonObject = wechatOAuth2Service.userInfo(code);
            /**
             * {"errcode": 40029, "errmsg": "invalid code, rid: 641d4deb-3fbe8396-6eeaa25b"}
             * {"errcode": 40163, "errmsg": "code been used, rid: 641d5a3b-31772d7d-22dda667}
             */
            if (jsonObject.get("errcode") != null)
                throw new RuntimeException(jsonObject.toJSONString());
            return wechatOAuth2Service.login(jsonObject.toJavaObject(WechatUserInfo.class));
        } catch (ResponseException e) {
            return error(e.getMessage());
        } catch (Exception e) {
            log.error("登录失败", e);
            return error("登录失败");
        }
    }

    @GetMapping("token")
    public AjaxResult token(HttpServletRequest request) {
        return success(wechatOAuth2Service.token(request));
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }


    /**
     * 当前登录人数
     * @return
     */
    @GetMapping("/login/num")
    public Long loginNum() {
        return redisCache.keys(LOGIN_TOKENS).stream().map(this::getUserIdByKey).distinct().count();
    }

    private Long getUserIdByKey(String key) {
        LoginUser user = redisCache.getCacheObject(key);
        return user.getUser().getUserId();
    }
}
